package com.brillilab.service.core.space.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.brillilab.common.utils.MyBeanUtils;
import com.brillilab.dao.mapper.space.BoxMapper;
import com.brillilab.dao.mapper.space.DeviceMapper;
import com.brillilab.dao.mapper.space.PanelMapper;
import com.brillilab.dao.mapper.space.RoomMapper;
import com.brillilab.dao.mapper.system.DictMapper;
import com.brillilab.domain.enums.common.IsDeleteEnum;
import com.brillilab.domain.enums.space.DeviceType;
import com.brillilab.domain.po.space.Box;
import com.brillilab.domain.po.space.Device;
import com.brillilab.domain.po.space.Panel;
import com.brillilab.domain.po.space.Room;
import com.brillilab.domain.po.system.Dict;
import com.brillilab.domain.vo.space.BoxVo;
import com.brillilab.domain.vo.space.DeviceVo;
import com.brillilab.domain.vo.space.PanelVo;
import com.brillilab.domain.vo.space.SpaceSearchVo;
import com.brillilab.service.core.space.IRoomService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;

/**
 * @author wuzhiyu
 * @Title: RoomServceImpl
 * @ProjectName brill_lab
 * @Description: TODO
 * @date 2018/11/139:54
 */
@Service
@Transactional
public class RoomServceImpl implements IRoomService {
    @Autowired
    private RoomMapper roomMapper;
    @Autowired
    private DeviceMapper deviceMapper;
    @Autowired
    private DictMapper dictMapper;
    @Autowired
    private PanelMapper panelMapper;
    @Autowired
    private BoxMapper boxMapper;

    @Override
    public Room add(Room room) {
        Assert.isTrue(roomMapper.insert(room) > 0, "数据保存失败");
        return room;
    }

    @Override
    public List<Room> list(Long labId) {
        LambdaQueryWrapper<Room> conditon = new QueryWrapper<Room>().lambda();
        conditon.eq(Room::getIsDelete, 0).eq(Room::getLabId, labId).orderByAsc(Room::getId);
        return roomMapper.selectList(conditon);
    }

    @Override
    public Room get(Long roomId) {
        return roomMapper.selectById(roomId);
    }

    @Override
    public boolean update(Long roomId, String name) {
        Room room = new Room();
        room.setId(roomId);
        room.setName(name);
        return roomMapper.updateById(room) > 0;
    }

    @Override
    public boolean delete(Long id) {
        LambdaQueryWrapper<Room> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Room::getId, id);
        Room room = new Room();
        room.setIsDelete(1);
        return roomMapper.update(room, wrapper) > 0;
    }

    @Override
    public SpaceSearchVo searchSpace(Long labId, Integer zone, Long reagentTypeId, Long labMemberId) {
        LambdaQueryWrapper<Dict> dictWrapper = new LambdaQueryWrapper<>();
        dictWrapper.eq(Dict::getType, "zone");
        List<Dict> zoneDict = dictMapper.selectList(dictWrapper);
        if (reagentTypeId == null && labMemberId == null) {
            Page<Device> devicePage = new Page<>(1, 20);
            LambdaQueryWrapper<Device> deviceWrapper = new LambdaQueryWrapper<>();
            deviceWrapper.eq(Device::getLabId, labId);
            deviceWrapper.eq(Device::getZone,zone);
            deviceWrapper.eq(Device::getDeviceType, DeviceType.DEVICE.getCode());
            deviceWrapper.eq(Device::getIsDelete, IsDeleteEnum.NO.getValue());
            deviceMapper.selectPage(devicePage, deviceWrapper);
            List<Device> deviceList = devicePage.getRecords();
            SpaceSearchVo result = new SpaceSearchVo();
            List<DeviceVo> voList = new ArrayList<>();
            result.setDeviceList(voList);
            deviceList.forEach(d -> {
                DeviceVo vo = new DeviceVo();
                MyBeanUtils.copyProperties(d, vo);
                vo.setZoneName(zoneDict.stream().filter(z -> z.getCode().equals(d.getZone())).findFirst().get().getName());
                voList.add(vo);
            });
            return result;
        } else {
            SpaceSearchVo result = new SpaceSearchVo();
            List<PanelVo> pVoList = new ArrayList<>();
            List<BoxVo> boxVoList = new ArrayList<>();
            Page<Panel> panelPage = new Page<>(1, 20);
            LambdaQueryWrapper<Panel> panelWrapper = new LambdaQueryWrapper<>();
            panelWrapper.eq(Panel::getLabId, labId);
            if (reagentTypeId != null) {
                panelWrapper.like(Panel::getUserReagentType, ","+reagentTypeId.toString()+",");
            }
            if (labMemberId == null || labMemberId > 0) {
                panelWrapper.eq(Panel::getLabMemberId, labMemberId);
            }
            panelWrapper.eq(Panel::getIsDelete, IsDeleteEnum.NO.getValue());
            if(zone!=null) {
                panelWrapper.eq(Panel::getZone, zone);
            }
            panelMapper.selectPage(panelPage, panelWrapper);
            List<Panel> panelList = panelPage.getRecords();
            result.setPanelList(pVoList);
            panelList.forEach(p -> {
                PanelVo vo = new PanelVo();
                MyBeanUtils.copyProperties(p, vo);
                vo.setZoneName(zoneDict.stream().filter(z -> z.getCode().equals(p.getZone())).findFirst().get().getName());
                pVoList.add(vo);
            });
            Page<Box> boxPage = new Page<>(1, 20);
            LambdaQueryWrapper<Box> boxWrapper = new LambdaQueryWrapper<>();
            boxWrapper.eq(Box::getLabId, labId);
            if (reagentTypeId != null) {
                boxWrapper.like(Box::getUserReagentType, ","+reagentTypeId.toString()+",");
            }
            if (labMemberId == null || labMemberId > 0) {
                boxWrapper.eq(Box::getLabMemberId, labMemberId);
            }
            boxWrapper.eq(Box::getIsDelete, IsDeleteEnum.NO.getValue());
            if(zone!=null) {
                boxWrapper.eq(Box::getZone, zone);
            }
            boxMapper.selectPage(boxPage, boxWrapper);
            List<Box> boxList = boxPage.getRecords();
            result.setBoxList(boxVoList);
            boxList.forEach(b -> {
                BoxVo vo = new BoxVo();
                MyBeanUtils.copyProperties(b, vo);
                vo.setZoneName(zoneDict.stream().filter(z -> z.getCode().equals(b.getZone())).findFirst().get().getName());
                boxVoList.add(vo);
            });
            return result;
        }
    }

}
